﻿using ProtocolImpl.Rs232;
using SerialPortExamples;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO.Ports;
using System.Windows;
using SerialPortExample.Model;
using System.Windows.Media.Animation;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Configuration;

namespace SerialPortExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        SerialPort _serialPort;
        SerialPortSetting serialPort;
        private bool isSerialPortOpen = false;
        //Logger logger;
        private Logger logger { get; set; }
        //string[] portNames = SerialPort.GetPortNames();
        Random random = new Random();

        private MainViewModel _viewModel;
        public MainWindow()
        {
            InitializeComponent();
            //List<double> temps = SerialPortSetting.temperatures;
            string[] portNames = SerialPort.GetPortNames();
            foreach (string portName in portNames)
            {
                comPortComboBox.Items.Add(portName);
            }
            if (comPortComboBox.Items.Count > 0)
            {
                comPortComboBox.SelectedIndex = 0;
            }
            _viewModel = new MainViewModel();
            DataContext = _viewModel;
            logger = Logger.GetInstance();
        }
        bool send = false;
        bool temperatureSend = false;
        private async void openCloseButton_Click(object sender, RoutedEventArgs e)
        {
            if (!isSerialPortOpen)
            {
                try
                {
                    string selectedPort = comPortComboBox.SelectedItem.ToString();
                    _serialPort = new SerialPort(selectedPort, 9600, Parity.None, 8, StopBits.One);
                    _serialPort.DataReceived += SerialPort_DataReceived;
                    _serialPort.ReceivedBytesThreshold = 103;
                    serialPort = new SerialPortSetting(_serialPort);
                    serialPort.Init();
                    isSerialPortOpen = true;
                    openCloseButton.Content = "关闭COM";
                 
                }
                catch (Exception ex)
                {
                    logger.WriteException(ex);
                }
            }
            else if (isSerialPortOpen)
            {
                logger.WriteLog("串口已关闭");
                _serialPort.Close();
                isSerialPortOpen = false;
                openCloseButton.Content = "打开COM";
                // 关闭串口时，设置send和temperatureSend为true，并更新按钮内容
                send = false;
                temperatureSend = false;

                // 显式更新按钮内容
                PWMSignalOutput.Content = "开始PWM信号输出";
                TempInfoGetButton.Content = "开始获取温度信息";
            }
        }

        private void PWMSignalOutput_Click(object sender, RoutedEventArgs e)
        {
            if (isSerialPortOpen)
            {
                byte[] dataLength = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                if (send)
                {
                    logger.WriteLog("停止发送数据:PWM信号输出控制");
                    PWMSignalOutput.Content = "开始PWM信号输出";
                    byte[] data = new byte[] { 0x00 };
                    Protocol protocol = new Protocol(0x01, data, dataLength);
                    serialPort.Send(protocol);
                    send = false;
                }
                else if (!send)
                {
                    logger.WriteLog("开始发送数据:PWM信号输出控制");
                    PWMSignalOutput.Content = "停止信号输出控制";
                    byte[] data = new byte[] { 0x01 };
                    Protocol protocol = new Protocol(0x01, data,dataLength);
                    serialPort.Send(protocol);
                    send = true;
                }
            }
            else
            {
                logger.WriteLog("请先打开COM");
            }
        }
        private void SendTime_Click(object sender, RoutedEventArgs e)
        {
            if (isSerialPortOpen)
            {
                string getTime = responseTime.Text.Trim();
                byte[] dataLength = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                if (int.TryParse(getTime, out int timeValue))
                {
                    logger.WriteLog("开始发送数据:下发相应时间");
                    int Time = timeValue * 2 ;
                    byte[] data = new byte[] { (byte)(Time & 0xFF) };
                    Protocol protocol = new Protocol(0x05, data, dataLength);
                    serialPort.Send(protocol);
                }
                else
                {
                    MessageBox.Show("请输入整数类型");
                }
            }
            else
            {
                logger.WriteLog("请先打开COM");
            }
        }

        private void TempInfoGetButton_Click(object sender, RoutedEventArgs e)
        {
            if (isSerialPortOpen)
            {
                byte[] dataLength = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                if (!temperatureSend)
                {
                    logger.WriteLog("开始发送数据:温度信息获取");
                    TempInfoGetButton.Content = "停止获取温度信息";
                    byte[] data = new byte[] { 0x01 };
                    Protocol protocol = new Protocol(0x02, data, dataLength);
                    serialPort.Send(protocol);
                    temperatureSend = true;
                }
                else if (temperatureSend)
                {
                    logger.WriteLog("停止发送数据:温度信息获取");
                    TempInfoGetButton.Content = "开始获取温度信息";
                    byte[] data = new byte[] { 0x00 };
                    Protocol protocol = new Protocol(0x02, data, dataLength);
                    serialPort.Send(protocol);
                    temperatureSend = false;
                }
            }
            else
            {
                logger.WriteLog("请先打开COM");
            }
        }
        private async void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            await Task.Run(() =>
            {
                try
                {
                    var (temperatures, dutyCycles, targetTemperature) = serialPort.Receive();
                    if(temperatures == null || dutyCycles == null) return;
                    for (int i = 0; i < temperatures.Length; i++)
                    {
                        //跨线程访问异常，_viewModel与UI主线程绑定
                        Dispatcher.Invoke(() =>
                        {
                            _viewModel.Images[i].TempCValue = temperatures[i] / 10;
                            _viewModel.Images[i].DutyCycle = dutyCycles[i];
                        });
                    }
                    //if(targetTemperature != _viewModel.Temperature) logger.WriteLogAsync($"接收到的目标温度[{targetTemperature}]与设置的目标温度不匹配[{_viewModel.Temperature}]");
                    
                }catch(TimeoutException ex)
                {
                    logger.WriteLogAsync("接收数据超时");
                }
            });
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if(logger.Logs.Count == 0) return;
            logger.Logs.Clear();
        }

        private void Open_Click(object sender, RoutedEventArgs e)
        {
            string folderPath = "C:\\PMOS\\Result\\";
            Process.Start("explorer.exe", folderPath);
        }

        private void SendTemperature_Click(object sender, RoutedEventArgs e)
        {
            if (isSerialPortOpen)
            {
                var temperature = _viewModel.Temperature * 10;
                if (temperature > ushort.MaxValue || temperature < 0)
                {
                    MessageBox.Show($"输入目标温度值异常，应在[0,{ushort.MaxValue}之间]");
                    return;
                }
                byte[] dataLength = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                ushort tempAsUShort = Convert.ToUInt16(temperature);
                logger.WriteLog("发送目标温度设置");
                byte[] data = new byte[2];
                data[0] = (byte)(tempAsUShort >> 8);
                data[1] = (byte)(tempAsUShort & 0xFF);
                Protocol protocol = new Protocol(0x06, data, dataLength);
                serialPort.Send(protocol);
            }
            else
            {
                logger.WriteLog("请先打开COM");
            }
        }
    }
}